        SUBT    > <wini>arm.NewEmulate.EmuTube - Tube emulation only

 [ :LNOT: tube
 ! 1, "Why are you assembling this file ???"
 ]

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Sit on FileV and FSCV to catch unknown *commands, stopping them from getting
; to the potentially destructive Filing Systems on this machine !

; In    wp valid, st vectors entered with wp valid !

LinkOntoFSVectors ENTRY "r0-r2"

        MOV     r0, #FSCV
        ADR     r1, FSControlHandler
        MOV     r2, wp
        SWI     XOS_Claim

        MOVVC   r0, #FileV
        ADRVC   r1, OSFileHandler
; ***^  MOV     r2, wp
        SWIVC   XOS_Claim

        MOV     r0, #0
        STR     r0, [wp, #wheretoexecuteit] ; No code loaded by command
                                        ; Do NOT clear lastwheretoexecuteit
        STRB    r0, [wp, #inosfile]     ; Not gone through OSFile once
        EXITS

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Must delink on errors and eventual return from OS_CLI. Also on Exit

; In    wp valid

DelinkFromFSVectors ENTRY "r0-r3"

        MOV     r0, #FSCV
        ADR     r1, FSControlHandler
        MOV     r2, wp
        SWI     XOS_Release

        MOV     r0, #FileV
        ADR     r1, OSFileHandler
        MOV     r2, wp                  ; r2 may be corrupted by failed release
        SWI     XOS_Release
        EXITS                           ; Don't care about errors in release

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Sit on FileV during OS_CLI so we can trap *LOAD etc.

; Rule No. 1: Don't do SWI OS_File in the OSFile handler without interlocks !

OSFileHandler ROUT

        Push    lr
        LDRB    r14, [wp, #inosfile]    ; Don't trap if we're in it
        TEQ     r14, #0
        Pull    pc, NE

        Push    "r1, r6, MR"            ; lr already stacked
        GetMR

        AND     r0, r0, #&FF            ; r0b is OSFile op

        TEQ     r0, #OSFile_Save
        TEQNE   r0, #OSFile_SaveStamp
        BEQ     %FT20

        TEQ     r0, #OSFile_Load        ; Suss OSFile op for lookup
        MOVEQ   r6, #OSFile_ReadInfo
        BEQ     %FT05

        TEQ     r0, #OSFile_LoadPathVar
        MOVEQ   r6, #OSFile_ReadPathVar
        Pull    "r1, r6, MR, pc", NE    ; Not interested in the other ops
                                        ; So pass on


05      MOV     r14, #1
        STRB    r14, [wp, #inosfile]    ; Modify flag - we're in now !

        ANDS    r14, r3, #&FF           ; If r3 <> 0 then we have to look
        BEQ     %FT10                   ; at the file's load address ourselves

        Push    r0                      ; Preserve given Load op
        MOV     r0, r6                  ; Use given ReadInfo op
 [ debug
 DREG r0,"Doing OS_File ",cc
 DSTRING r1,", filename "
 ]
        SWI     XOS_File                ; 'Not found' or 'Is a dir' given
        ADDVS   sp, sp, #4
        BVS     %FA30                   ; Exit maintaining error
        Pull    r0

10      MOV     r3, r2, ASR #8          ; FFFtttxx ?
        LDR     r14, =&FFFFFBBC         ; Is it a BBC ROM type file ?
        CMP     r3, r14                 ; (Preserve r0 you idiot !)
        MOVEQ   r2, #&8000              ; Load at &8000 if so

        CMP     r3, #&FFFFFF00          ; Host addresses in FFFF0000..FFFF8000
        BLO     %FT15                   ; get rounded into 64K
        CMP     r3, #&FFFFFF80
        BICLS   r2, r2, #&FF000000      ; Round down into 64K -> 0000xxxx
        BICLS   r2, r2, #&00FF0000

15      MOV     r3, r2, ASR #20         ; All other date stamped things are bad
        CMP     r3, #-1                 ; ie BASIL progs, data
        BEQ     %FT99

        CMP     r2, #RamLimit           ; If file loading below given address
                                        ; then modify it into emulator space
        ADDLO   r2, r2, MR              ; LOAD: load address +:= MR
        MOV     r3, #0                  ; As specified by this r2 always
        B       %FT25                   ; Do the load


20      MOV     r14, #1
        STRB    r14, [wp, #inosfile]    ; Modify flag - we're in now !

        CMP     r4, #RamLimit           ; If both file addr below given address
        CMPLO   r5, #RamLimit           ; then modify them into emulator space
        ADDLO   r4, r4, MR              ; SAVE: start address +:= MR
        ADDLO   r5, r5, MR              ; SAVE: end address   +:= MR
                                        ; (allows saves from Twin etc.)

25
 [ debug
 DREG r0,"Doing OS_File ",cc
 DSTRING r1,", filename "
 ]
        SWI     XOS_File                ; Do the load / save

30      MOV     r14, #0                 ; Coming out
        STRB    r14, [wp, #inosfile]
        Pull    "r1, r6, MR, lr, pc"    ; Claim vector


99      ADR     r0, ErrorBlock_6502CantLoadFile
        SETV
        Pull    "r1, r6, MR, lr, pc"    ; VSet too. Claim vector


        MakeErrorBlock 6502CantLoadFile

        MakeErrorBlock 6502CantRunFile

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; If a star command gets round as far as FSCV I want to stop it and load a file
; if possible, eg. VIEW. Try to run the file using the 6502 code path

; In    r1 -> filename to use
;       wp valid

FSControlHandler ROUT

        TEQ     r0, #FSControl_Run
        MOVNE   pc, lr                  ; Let all others pass me by

;                0*4 1*4 2*4 3*4 4*4 5*4 6*4 7*4 8*4   9*4
        Push    "r0, r1, r2, r3, r4, r5, r6, MR, lr" ; pc for claim on stack
        GetMR

        MOV     r0, #OSFile_ReadPathVar
        addr    r4, RunPath6502Name
 [ debug
 DSTRING r1,"Trying to run "
 ]
        SWI     XOS_File
        BVS     %FA98
 [ debug
 DREG r0,"Object type ",cc
 DREG r2,", load and exec addresses ",cc
 DREG r3
 ]
        TEQ     r0, #1                  ; Is it a file ?
        BNE     %FT95                   ; If not, explode violently

        CMP     r2, #0                  ; Is it a undated command file ?
        CMPEQ   r3, #-1                 ; [Pass it on to FileSwitch to *Run]    
        LDRNE   r14, =&FFFFFFFE         ; Is it a dated command file ?
        CMPNE   r14, r2, ASR #8         ; [Pass it on to FileSwitch to *Run]

        LDRNE   r14, =&FFFFFFFC         ; Is it a transient file ?
        CMPNE   r14, r2, ASR #8         ; [Pass it on to FileSwitch to *Run]
        BEQ     %FA90

        LDR     r14, =&FFFFFBBC         ; Is it a BBC ROM type file ?
        CMP     r14, r2, ASR #8
        MOVEQ   r2, #&8000              ; [Load at &8000 in 6502 space]
        MOVEQ   r3, r2                  ; [and execute there]

        MOV     r0, r2, ASR #16         ; FFFFxxxx ? (ie. Host address)
        CMP     r0, #-1
        BEQ     %FT25                   ; Ok when masked out

        MOV     r0, r2, ASR #20         ; All other date stamped things get
        CMP     r0, #-1                 ; faulted
        BNE     %FT25

19      addr    r0, ErrorBlock_6502CantRunFile
        SETV
        B       %FT98

25      LDR     r6, [wp, #OSOrigin_copy]

        BIC     r2, r2, #&FF000000      ; Where shall we load it ?
        BIC     r2, r2, #&00FF0000      ; Round down into 64K region

        ADD     r0, r2, r4              ; And where would it end ?
        CMP     r0, r6                  ; Files may only be run below the TOS
        BHI     %BA19                   ; and must not crap on it

        BIC     r3, r3, #&FF000000      ; Where shall we execute it ?
        BIC     r3, r3, #&00FF0000      ; Round down into 64K region

        CMP     r3, r6                  ; Files may only be run below the TOS
        BHI     %BA19

        STR     r3, [wp, #wheretoexecuteit] ; To be picked up the the TOS
        STR     r3, [wp, #lastwheretoexecuteit]

        MOV     r0, #OSFile_LoadPathVar
        addr    r4, RunPath6502Name
        MOV     r3, #0                  ; Load at specified address
        SWI     XOS_File                ; OSFile will add in emulator space

98      STRVS   r0, [sp]
        Pull    "r0-r6, MR, lr, pc"     ; Claim vector



; Not a file, so winge about it

95      MOV     r2, r0
        MOV     r0, #OSFile_MakeError
        SWI     XOS_File
        B       %BT98


; Pass it down to FileSwitch to *Run.

90      MOV     r2, r1                  ; Make 'Run6502:filename'
        ADD     r1, wp, #TempString
        ADR     r14, RunnerPrefix
        LDMIA   r14, {r0, r14}
        STMIA   r1!, {r0, r14}
        BL      strcpy
        ADD     r1, wp, #TempString
        MOV     r0, #FSControl_Run
 [ debug
 DSTRING r1,"New filename is "
 LDR r14, [sp, #8*4]
 DREG r14,"Continuing on vector to address "
 ]
        Push    pc                      ; +0: Fake return address of %FT96
        LDR     MR, [sp, #7*4 + 4]      ; +4: r11in (+4 for faked vectorreturn)
        LDR     pc, [sp, #8*4 + 4]      ; +8: r14in (+4 for faked vectorreturn)

96      STRVS   r0, [sp]                ; +12
        Pull    "r0-r6, MR, lr, pc"     ; Claim vector, restoring caller's regs
                                        ; including r1. I can't see anyone
                                        ; relying on this, but I'm a good boy
RunnerPrefix
        DCB     "Run6"                  ; Picked up as words
        DCB     "502:"

        LTORG

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

        MACRO
$label  LoadByte $byte, $addr
$label  LDRB    $byte, [MR, $addr]
        MEND

        MACRO
$label  LoadByteFNZ $byte, $addr
$label  LDRB    $byte, [MR, $addr]
        MEND

        MACRO
$label  StoreByte $byte, $addr
$label  STRB    $byte, [MR, $addr]
        MEND

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

        LTORG

        LNK     EmuOpcode
